/**
 * funciona como updater de GameObjects de juegos de plataforma. Maneja, gravedad, caida libre y colisiones
 * con plataformas.
 * @param {GameObject} go           cuerpo a manipular
 * @param {Array<GameObject>} collideables objetos con los que el cuerpo a manipular puede colisionar
 * @param {Number} gravity      magnitud de gravedad
 * @param {Number} maxSpeedY    maxima velocidad que el cuerpo puede adquirir en eje y.
 */
SimplePlatformerCollisionUpdater = function(go, collideables, gravity, maxSpeedY) {
    Updater.call(this, go);
    this.collideables = collideables;
    this.maxSpeedY = maxSpeedY || 5;
    this.gravity = gravity || 0.2;
};

SimplePlatformerCollisionUpdater.prototype = Object.create(Updater.prototype);

SimplePlatformerCollisionUpdater.prototype.run = function() {
    var collideables = this.collideables;
    var gravity = this.gravity;
    var maxSpeedY = this.maxSpeedY;
    var obj = this.gameObject;


    var moveX = obj.vx;
    /*var moveY = gravity;*/
    var moveY = obj.vy;
    var bounds = getBounds(obj);

    var collisions = calculateRectCollision(obj, collideables);


    var groundHit = false;
    if (collisions) {
        for (var i = 0; i < collisions.length; i++) {
            var inter = collisions[i];
            var cbounds = getBounds(inter.collisioned);

            var diffX = bounds.x - cbounds.x;
            var signX = diffX / Math.abs(diffX);
            var diffY = bounds.y - cbounds.y;
            var signY = diffY / Math.abs(diffY);

            /*signY es positivo si la colision es de arriba a abajo.es
             negativo si la colision es de abajo hacia arriba*/
            var roofHit = signY > 0 ? true : false;

            /*si altura de la colision es superior a la anchura de la misma, entonces
            la colision fue frontal.*/
            if (inter.height >= inter.width) {
                writeOnCanvas("x collision!", 25, 75, "blue");
                moveX = Math.ceil(inter.width) * signX;
                moveX = moveX || signX;
            } else {
                writeOnCanvas("y collision!", 150, 75, "blue");
                if (roofHit) {
                    moveY = Math.ceil(inter.height) * signY;
                } else {
                    //si no se golpeo el techo entonces se toco el suelo
                    if (!obj.onGround) {
                        /* si el cuerpo toca el suelo despues de una caida, se corrige su 
                        posicion en y para que no atraviese la plataforma
                        */
                        obj.y += Math.floor(inter.height) * signY;
                    }
                    groundHit = true;
                }
            }
        }
    } //if (collisions)

    /*si se toco el suelo entonces la velocidad en y se setea en
cero, de lo contrario se acelera la caida del cuerpo
*/
    if (groundHit) {
        moveY = obj.vy = 0;
        obj.onGround = true;
    } else {
        //si el cuerpo no esta en el piso, entonces esta cayendo
        obj.onGround = false;
        if (obj.vy < maxSpeedY)
            obj.vy += gravity;
        else
            obj.vy = maxSpeedY;

        moveY = obj.vy;
    }


    obj.move(moveX, moveY);
};
